package com.example.xcpeekaboo.game;

import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.Location;
import org.bukkit.entity.Firework;
import org.bukkit.entity.EntityType;
import org.bukkit.FireworkEffect;
import org.bukkit.Color;
import org.bukkit.inventory.meta.FireworkMeta;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GameManager {
    private static GameManager instance;
    private boolean isGameRunning;
    private List<Player> seekers;
    private List<Player> hiders;
    private Map<Player, Boolean> playerStatus; // true表示存活，false表示被抓
    private int gameTime; // 游戏时长（秒）
    private int prepareTime; // 准备时间（秒）
    private BukkitTask gameTimer;
    private BukkitTask prepareTimer;
    private final Plugin plugin;
    private final List<String> allowedCommands;
    private Location seekerSpawnLocation; // 寻找者释放位置
    private Location hiderSpawnLocation; // 躲藏者释放位置
    private Location gameSpawnLocation; // 游戏出生点位置
    private final Map<Player, BukkitTask> waitingTasks; // 存储每个玩家的等待提示任务
    
    public enum GamePhase {
        WAITING,
        STARTED,
        HIDERS_RELEASED,
        SEEKERS_RELEASED
    }
    
    private GamePhase currentPhase;

    private GameManager(Plugin plugin) {
        this.plugin = plugin;
        this.isGameRunning = false;
        this.seekers = new ArrayList<>();
        this.hiders = new ArrayList<>();
        this.playerStatus = new HashMap<>();
        this.gameTime = 300; // 默认游戏时长5分钟
        this.prepareTime = 30; // 默认准备时间30秒
        this.gameTimer = null;
        this.prepareTimer = null;
        this.allowedCommands = new ArrayList<>();
        this.allowedCommands.add("xcpkbquit"); // 只允许退出指令
        this.seekerSpawnLocation = null;
        this.hiderSpawnLocation = null;
        this.waitingTasks = new HashMap<>();
        this.currentPhase = GamePhase.WAITING;
    }

    public static GameManager getInstance(Plugin plugin) {
        if (instance == null) {
            instance = new GameManager(plugin);
        }
        return instance;
    }

    public static GameManager getInstance() {
        if (instance == null) {
            throw new IllegalStateException("GameManager has not been initialized with a plugin instance");
        }
        return instance;
    }

    public boolean isGameRunning() {
        return isGameRunning;
    }

    public void setGameRunning(boolean gameRunning) {
        isGameRunning = gameRunning;
        if (gameRunning) {
            startPrepareTimer();
        } else {
            stopAllTimers();
        }
    }

    public List<Player> getSeekers() {
        return seekers;
    }

    public List<Player> getHiders() {
        return hiders;
    }

    public void addSeeker(Player player) {
        if (!seekers.contains(player)) {
            seekers.add(player);
            playerStatus.put(player, true);
        }
    }

    public void addHider(Player player) {
        if (!hiders.contains(player)) {
            hiders.add(player);
            playerStatus.put(player, true);
        }
    }

    public void removePlayer(Player player) {
        seekers.remove(player);
        hiders.remove(player);
        playerStatus.remove(player);
        cancelWaitingTask(player);
    }

    public void removeSeeker(Player player) {
        seekers.remove(player);
        playerStatus.remove(player);
    }

    public void removeHider(Player player) {
        hiders.remove(player);
        playerStatus.remove(player);
    }

    public void resetGame() {
        stopAllTimers();
        cancelAllWaitingTasks();
        isGameRunning = false;
        seekers.clear();
        hiders.clear();
        playerStatus.clear();
    }

    private void startPrepareTimer() {
        if (prepareTimer != null) {
            prepareTimer.cancel();
        }

        currentPhase = GamePhase.STARTED;
        plugin.getServer().broadcastMessage("§a游戏开始！5秒后释放躲藏者！");

        prepareTimer = new BukkitRunnable() {
            int timeLeft = 35; // 5秒后释放躲藏者，再30秒后释放寻找者

            @Override
            public void run() {
                if (timeLeft == 30) { // 5秒后
                    currentPhase = GamePhase.HIDERS_RELEASED;
                    // 传送躲藏者到指定位置
                    if (hiderSpawnLocation != null) {
                        for (Player hider : hiders) {
                            hider.teleport(hiderSpawnLocation);
                            // 在躲藏者被释放时进行伪装
                            DisguiseManager.getInstance().disguisePlayer(hider);
                            // 在躲藏者周围生成生物
                            spawnRandomEntitiesAroundPlayer(hider);
                        }
                    }
                    plugin.getServer().broadcastMessage("§a躲藏者已被释放！30秒后释放寻找者！");
                } else if (timeLeft <= 0) {
                    currentPhase = GamePhase.SEEKERS_RELEASED;
                    plugin.getServer().broadcastMessage("§a准备时间结束！寻找者被释放！游戏正式开始！");
                    teleportSeekersToSpawn();
                    startGameTimer();
                    this.cancel();
                    return;
                }

                if ((timeLeft <= 10 || timeLeft % 10 == 0) && timeLeft <= 30) {
                    plugin.getServer().broadcastMessage("§e寻找者将在 " + timeLeft + " 秒后被释放！");
                }
                timeLeft--;
            }
        }.runTaskTimer(plugin, 0L, 20L);
    }

    private void spawnRandomEntitiesAroundPlayer(Player player) {
        Location playerLoc = player.getLocation();
        EntityType[] entityTypes = {
            EntityType.COW, EntityType.SHEEP, EntityType.PIG,
            EntityType.CHICKEN, EntityType.RABBIT, EntityType.HORSE,
            EntityType.DONKEY, EntityType.LLAMA, EntityType.WOLF,
            EntityType.CAT, EntityType.MOOSHROOM
        };

        // 在玩家周围30格半径内随机生成10-15个生物
        int count = 10 + (int)(Math.random() * 6);
        for (int i = 0; i < count; i++) {
            // 随机选择生物类型
            EntityType type = entityTypes[(int)(Math.random() * entityTypes.length)];
            
            // 在玩家周围随机位置生成生物
            double angle = Math.random() * 2 * Math.PI;
            double radius = Math.random() * 30;
            double x = playerLoc.getX() + radius * Math.cos(angle);
            double z = playerLoc.getZ() + radius * Math.sin(angle);
            Location spawnLoc = new Location(playerLoc.getWorld(), x, playerLoc.getY(), z);
            
            // 确保生成位置在固体方块上
            spawnLoc.setY(spawnLoc.getWorld().getHighestBlockYAt(spawnLoc));
            
            // 生成生物
            player.getWorld().spawnEntity(spawnLoc, type);
        }
    }

    public void startWaitingTask(Player player) {
        cancelWaitingTask(player);
        BukkitTask task = new BukkitRunnable() {
            @Override
            public void run() {
                if (!isGameRunning) {
                    player.sendTitle("§6躲猫猫", "§e等待管理员开启游戏...", 10, 70, 20);
                } else {
                    cancelWaitingTask(player);
                }
            }
        }.runTaskTimer(plugin, 0L, 100L); // 每5秒显示一次
        waitingTasks.put(player, task);
    }

    public void cancelWaitingTask(Player player) {
        BukkitTask task = waitingTasks.remove(player);
        if (task != null) {
            task.cancel();
        }
    }

    private void cancelAllWaitingTasks() {
        for (BukkitTask task : waitingTasks.values()) {
            task.cancel();
        }
        waitingTasks.clear();
    }

    private void handleVictory(String winnerType, String message) {
        plugin.getServer().broadcastMessage(message);
        
        // 获取所有参与游戏的玩家
        List<Player> allPlayers = new ArrayList<>();
        allPlayers.addAll(seekers);
        allPlayers.addAll(hiders);
        
        // 为每个玩家显示Title
        String title = "§6游戏结束";
        String subtitle = winnerType.equals("seekers") ? "§c寻找者获胜！" : "§a躲藏者获胜！";
        for (Player player : allPlayers) {
            player.sendTitle(title, subtitle, 10, 70, 20);
        }
        
        // 为胜利方玩家施放烟花
        List<Player> winners = winnerType.equals("seekers") ? seekers : hiders;
        for (Player winner : winners) {
            spawnFirework(winner.getLocation());
        }

        // 10秒后移除伪装并恢复所有躲藏者为生存模式
        new BukkitRunnable() {
            @Override
            public void run() {
                DisguiseManager disguiseManager = DisguiseManager.getInstance();
                for (Player hider : hiders) {
                    disguiseManager.undisguisePlayer(hider);
                    hider.setGameMode(org.bukkit.GameMode.SURVIVAL);
                    hider.sendMessage("§a你已被恢复为生存模式！游戏结束！");
                }
                // 将所有玩家传送回出生点
                teleportAllPlayersToGameSpawn();
                // 在恢复玩家状态后再重置游戏
                resetGame();
            }
        }.runTaskLater(plugin, 200L); // 200 ticks = 10 seconds
    }
    
    private void spawnFirework(Location location) {
        Firework firework = (Firework) location.getWorld().spawnEntity(location, EntityType.FIREWORK_ROCKET);
        FireworkMeta meta = firework.getFireworkMeta();
        
        // 设置烟花效果
        FireworkEffect effect = FireworkEffect.builder()
            .withColor(Color.RED, Color.YELLOW, Color.BLUE)
            .with(FireworkEffect.Type.BALL_LARGE)
            .withFlicker()
            .withTrail()
            .build();
            
        meta.addEffect(effect);
        meta.setPower(1); // 设置烟花飞行时间
        firework.setFireworkMeta(meta);
    }
    
    private void checkAllHidersCaught() {
        boolean allCaught = true;
        for (Player hider : hiders) {
            if (isPlayerAlive(hider)) {
                allCaught = false;
                break;
            }
        }
        if (allCaught && isGameRunning) {
            handleVictory("seekers", "§c所有躲藏者都被抓住了！寻找者获胜！");
        }
    }
    
    private void startGameTimer() {
        if (gameTimer != null) {
            gameTimer.cancel();
        }
        
        gameTimer = new BukkitRunnable() {
            // 疯狂模式标记
            boolean frenzyTriggered = false;
            int timeLeft = gameTime;

            @Override
            public void run() {
                // 检查是否进入最后30秒疯狂模式
                if (timeLeft <= 30 && !frenzyTriggered) {
                    frenzyTriggered = true;
                    triggerFrenzyMode();
                }
                
                if (timeLeft <= 0) {
                    handleVictory("hiders", "§c游戏时间结束！躲藏者获胜！");
                    this.cancel();
                    return;
                }

                if (timeLeft % 60 == 0 || timeLeft <= 10) {
                    plugin.getServer().broadcastMessage("§e游戏还剩 " + timeLeft + " 秒！");
                }
                timeLeft--;
            }
        }.runTaskTimer(plugin, 0L, 20L);
    }

    private void stopAllTimers() {
        if (prepareTimer != null) {
            prepareTimer.cancel();
            prepareTimer = null;
        }
        if (gameTimer != null) {
            gameTimer.cancel();
            gameTimer = null;
        }
    }
    
    private void triggerFrenzyMode() {
        // 在屏幕中央显示疯狂模式提示
        for (Player player : plugin.getServer().getOnlinePlayers()) {
            player.sendTitle("§c疯狂模式", "§e游戏最后30秒！", 10, 70, 20);
        }
        
        // 为寻找者增加10%移速
        for (Player seeker : seekers) {
            seeker.setWalkSpeed(Math.min(0.2f, seeker.getWalkSpeed() * 1.1f));
            seeker.sendMessage("§6[疯狂模式] 你的移动速度增加了10%！");
        }
        
        // 为躲藏者增加5%移速并给予发光效果
        for (Player hider : hiders) {
            hider.setWalkSpeed(Math.min(0.2f, hider.getWalkSpeed() * 1.05f));
            hider.sendMessage("§6[疯狂模式] 你的移动速度增加了5%！");
            
            // 给予5秒发光效果
            hider.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, 100, 0));
            
            // 5秒后取消发光效果
            new BukkitRunnable() {
                @Override
                public void run() {
                    hider.removePotionEffect(PotionEffectType.GLOWING);
                    hider.sendMessage("§7[疯狂模式] 你的发光效果已消失");
                }
            }.runTaskLater(plugin, 100);
        }
        
        plugin.getServer().broadcastMessage("§c§l疯狂模式已激活！游戏最后30秒！");
    }

    public boolean isSeeker(Player player) {
        return seekers.contains(player);
    }

    public boolean isHider(Player player) {
        return hiders.contains(player);
    }

    public boolean isPlayerAlive(Player player) {
        return playerStatus.getOrDefault(player, false);
    }

    public void setPlayerCaught(Player player) {
        if (hiders.contains(player)) {
            playerStatus.put(player, false);
            // 检查是否所有躲藏者都被抓住了
            checkAllHidersCaught();
        }
    }

    public boolean isCommandAllowed(String command) {
        return !isGameRunning || allowedCommands.contains(command.toLowerCase());
    }

    public void setSeekerSpawnLocation(Location location) {
        this.seekerSpawnLocation = location;
    }

    public void setHiderSpawnLocation(Location location) {
        this.hiderSpawnLocation = location;
    }

    public void teleportSeekersToSpawn() {
        if (seekerSpawnLocation != null) {
            for (Player seeker : seekers) {
                seeker.teleport(seekerSpawnLocation);
            }
        }
    }

    public Location getGameSpawnLocation() {
        return this.gameSpawnLocation;
    }
    
    public void setGameSpawnLocation(Location location) {
        this.gameSpawnLocation = location;
    }

    public void teleportToGameSpawn(Player player) {
        if (gameSpawnLocation != null) {
            player.teleport(gameSpawnLocation);
        }
    }

    public void teleportAllPlayersToGameSpawn() {
        if (gameSpawnLocation != null) {
            for (Player player : seekers) {
                player.teleport(gameSpawnLocation);
            }
            for (Player player : hiders) {
                player.teleport(gameSpawnLocation);
            }
        }
    }
}